package com.a01_2021.thousandstimes.general.jwt.controller;

import com.a01_2021.thousandstimes.exception.CustomException;
import com.a01_2021.thousandstimes.exception.CustomExceptionType;
import com.a01_2021.thousandstimes.general.jwt.service.JwtAuthService;
import com.a01_2021.thousandstimes.saas.entity.UserMapping;
import com.a01_2021.thousandstimes.saas.service.IUserMappingService;
import com.a01_2021.thousandstimes.utils.AjaxResponse;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;

/**
 * @Author E1xP@foxmail.com
 * @Version 1.0
 * @PACKAGE_NAME com.a01_2021.thousandstimes.auth.jwt
 * @CLASS_NAME JwtAuthController
 * @Description TODO Jwt令牌授权Controller
 * @Date 2021/2/23 下午 9:19
 **/
@RestController
@RequestMapping("/jwt")
public class JwtAuthController {

    @Resource
    private JwtAuthService jwtAuthService;

    @Resource
    private IUserMappingService userMappingService;

    @Value("${jwt.expiration}")
    private long EXPIRE_TIME;

    /**
     * 登录获取Jwt令牌
     *
     * @param username   用户名
     * @param password   密码
     * @param instanceId 所属实例id
     * @return 返还认证响应
     */
    @DS("#header.instanceid")
    @PostMapping("authentication")
    public AjaxResponse login(String username, String password, @RequestHeader("instanceid") String instanceId) {
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return AjaxResponse.error(CustomExceptionType.USER_INPUT_ERROR, "用户名或密码不能为空");
        }
        if (StringUtils.isEmpty(instanceId))
            return AjaxResponse.error(CustomExceptionType.USER_INPUT_ERROR, "缺失实例id");
        try {
            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("expire", EXPIRE_TIME / 1000);
            resultMap.put("instanceId", instanceId);
            resultMap.put("username", username);
            resultMap.put("jwtToken", jwtAuthService.login(username, password, instanceId));
            return AjaxResponse.success(resultMap);
        } catch (CustomException e) {
            return AjaxResponse.error(e);
        }
    }

    /**
     * 通过用户名查询实例id
     *
     * @param username 用户名
     * @return AjaxResponse
     * @throws CustomException 若实例中不存在映射则返还该异常
     */
    @PostMapping("getInstance")
    public AjaxResponse getInstance(String username) throws CustomException {
        UserMapping userMapping = userMappingService.getUserMapping(username);
        if (userMapping == null) {
            return AjaxResponse.success("master");
        }
        return AjaxResponse.success(userMapping.getInstanceId().toString());
    }

    /**
     * 根据Jwt令牌
     *
     * @param token 旧令牌
     * @return 返还刷新后令牌(若令牌过期则返还Null
     */
    @DS("#header.instanceid")
    @PostMapping("refreshtoken")
    public AjaxResponse refresh(@RequestHeader("${jwt.header}") String token) {
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("accessToken", token);
        resultMap.put("refreshToken", jwtAuthService.refreshToken(token));
        resultMap.put("expire", EXPIRE_TIME / 1000);
        return AjaxResponse.success(resultMap);
    }
}
